﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1.CSharpProgrammingGuide
{
    internal class ProgrammingConcepts
    {
        public static void Show()
        {
            /*// 赋值兼容性
            string str = "test";
            // object的子类都可以赋值给object变量
            object obj = str;

            // 协变 ：子类数组赋值给父类数组
            IEnumerable<string> strings = new List<string>();
            // 可以这样赋值
            IEnumerable<object> objects = strings;

            // 逆变
            static void SetObject(object obj) { }
            Action<object> actObject = SetObject;

            Action<string> actString = actObject;

            object[] array = new string[10];
            array[0] = 10;
            */

            // 协变和逆变针对泛型委托来说的。
            static object GetObject() { return null; }
            static void SetObject(object obj) { }

            static string GetString() { return ""; }
            static void SetString(string str) { }

            // 协变：一个委托返回object类型，可以把返回字符串类型的方法赋值给它
            Func<object> del = GetString;

            // 逆变：一个委托指定string类型的参数，但是你可以把一个需要object类型参数的方法赋值给他
            Action<string> del2 = SetObject;

            // 在 .Net Framework4之后 C#允许在泛型接口和泛型委托中使用协变逆变自动隐士转换类型。
            // 下面的例子展示了泛型接口中引用类型的隐士转换
            // 协变：是可以把子类泛型赋值个父类泛型。
           /* IEnumerable<string> strings = new List<string>();
            IEnumerable<object> objects = strings;

            IEnumerable<int> integers = new List<int>();
            IEnumerable<object> objs = integers;*/
        }


    }
}
